﻿using System.Xml.Linq;

using WXWorkSvc.Common.Extensions;
using WXWorkSvc.Models;

namespace WXWorkSvc.Controllers;

[Route("api/[controller]")]
[ApiController]
public class CommandController : ControllerBase
{
    private readonly ILogger<CommandController> _logger;
    private readonly Cryptography _Cryptography;
    private readonly WXWork3rd _wx;
    private readonly WXDbContext _db;
    public CommandController(ILogger<CommandController> logger, Cryptography cryptography, WXWork3rd wx, WXDbContext db)
    {
        _logger = logger;
        _Cryptography = cryptography;
        _wx = wx;
        _db = db;
    }

    [HttpGet]
    public string Get(string msg_signature, string timestamp, string nonce, string echostr)
    {
        _Cryptography.VerifyURL(msg_signature, timestamp, nonce, echostr, out var decryptMsg, out _);
        return decryptMsg!;
    }
    [HttpPost]

    public async Task<string> Post(string msg_signature, string timestamp, string nonce)
    {

        //        var bodyxml = """"
        //<xml>
        //<ToUserName><![CDATA[ww42dc3a783ec7a139]]></ToUserName>
        //<Encrypt><![CDATA[plck5FuJFzFsQeW4/qSRR9hXiER+iy9W5bxMoX4hbQC0BpvVe3rHq9vCAq1hnR9y5MS2IhrMRHN2FTPMJE1oqRHm+XvIVExNDTF6B7JxfbLCBJpxTZtiFqAZiUKFrwd3CAGXj7t78yEJCcrTjlDUQUvogsyt5ebi4Z2sMCpOqlPTJBPbjn+VPfses7Tu2l52zIGuCFr6ULU5u1lO5RGjCpjAwzT1W+ZsSk4cfvnKC48zPTh1ivgfcd3XURQjjOe5p71aSN8v7CP6MmuX7Tp3WZahNfqvsw0VkXKDx9hj4LK+uVeSu10rK1+chgjAyH4AlEEaXakGa5VZfWJQph9H342PPimH+Ni35XgpahxCqRTJAlNxbylAZncT1M9pwlK9]]></Encrypt>
        //<AgentID><![CDATA[]]></AgentID>
        //</xml>
        //"""";
        //MemoryStream ms = new MemoryStream();
        //Request.Body.CopyTo(ms);

        try
        {
            var streamRead = new StreamReader(Request.Body);
            var bodyXml = await streamRead.ReadToEndAsync();


            XElement xe = XElement.Parse(bodyXml);
            var encryptMsg = xe.Element("Encrypt")!.Value;

            //_logger.LogInformation(encryptMsg);
            if (!_Cryptography.VerifyURL(msg_signature, timestamp, nonce, encryptMsg, out var decryptMsg, out var receiveId))
                return "";

            _logger.LogInformation(decryptMsg + "\r\n" + receiveId);
            var xe1 = XElement.Parse(decryptMsg);
            switch (xe1.Element("InfoType")!.Value)
            {
                case "suite_ticket":
                    {
                        /*
                <xml>
                    <SuiteId><![CDATA[ww42dc3a783ec7a139]]></SuiteId>
                    <InfoType><![CDATA[suite_ticket]]></InfoType>
                    <TimeStamp>1702870620</TimeStamp>
                    <SuiteTicket><![CDATA[du0vN53c2DxyCLqfVKnMhkyyWDKslnFH4G9ex0Kh98j34GD7J3qUAsZfBw3H5gxh]]></SuiteTicket>
                </xml>
                        */

                        var count = await _db.Suites.Where(ii => ii.Id == xe1.Element("SuiteId")!.Value).ExecuteUpdateAsync(ii => ii.SetProperty(jj => jj.Ticket, xe1.Element("SuiteTicket")!.Value).SetProperty(jj => jj.DTTicket, DateTime.Now));

                        if (count == 0)
                            _logger.LogError($"保存{xe1.Element("SuiteId")!.Value}的Ticket {xe1.Element("SuiteTicket")!.Value}失败");
                        break;
                    }
                case "create_auth":
                    {
                        await _wx.CreateAuthAsync(xe1.Element("SuiteId")!.Value, xe1.Element("AuthCode")!.Value);
                        break;
                    }
                case "change_auth":
                    {
                        await _wx.GetCorpAuthInfoAsync(xe1.Element("SuiteId")!.Value, xe1.Element("AuthCorpId")!.Value);
                        break;
                    }
                case "cancel_auth":
                    {
                        var corpId = xe1.Element("AuthCorpId")!.Value;
                        var suiteId = xe1.Element("SuiteId")!.Value;
                        await _db.Agents.Where(ii => ii.SuiteId == suiteId && ii.CorpId == corpId).ExecuteDeleteAsync();
                        await _db.Users.Where(ii => ii.SuiteId == suiteId && ii.CorpId == corpId).ExecuteDeleteAsync();
                        if (!await _db.Agents.AnyAsync(ii => ii.CorpId == corpId))
                            await _db.Corps.Where(ii => ii.Id == corpId).ExecuteUpdateAsync(ii => ii.SetProperty(jj => jj.IsAuth, false).SetProperty(jj => jj.Dt, DateTime.Now));
                        break;
                    }
            }

            return "success";
        }
        catch (Exception ex)
        {
            _logger.LogError(ex.ToString());
            return "";
        }
    }

}

